package hu.bme.aut.consulttime.client.components;

import java.util.Date;
import java.util.List;

import gwtupload.client.IUploadStatus.Status;
import gwtupload.client.IUploader;
import gwtupload.client.IUploader.UploadedInfo;
import gwtupload.client.MultiUploader;
import hu.bme.aut.consulttime.client.EvaluationService;
import hu.bme.aut.consulttime.client.EvaluationServiceAsync;
import hu.bme.aut.consulttime.client.LogService;
import hu.bme.aut.consulttime.client.LogServiceAsync;
import hu.bme.aut.consulttime.client.ProjectService;
import hu.bme.aut.consulttime.client.ProjectServiceAsync;
import hu.bme.aut.consulttime.client.TeamService;
import hu.bme.aut.consulttime.client.TeamServiceAsync;
import hu.bme.aut.consulttime.client.ToDoService;
import hu.bme.aut.consulttime.client.ToDoServiceAsync;
import hu.bme.aut.consulttime.entitydtos.EvaluationDTO;
import hu.bme.aut.consulttime.entitydtos.LogDTO;
import hu.bme.aut.consulttime.entitydtos.ToDoDTO;
import hu.bme.aut.consulttime.entitydtos.UserDTO;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;


public class StudentToDoPage extends Composite {
	private long teamId;
	private long projectId;
	private long userId;
	private List<UserDTO> teamMembers;
	private List<UserDTO> projectTutors;
	long selectedTeamMemberUserId;

	private VerticalPanel mainPanel;
	private ListBox selectTeamMemberListBox;
	private Tree toDoTree;

	private TeamServiceAsync teamService = GWT.create(TeamService.class);
	private ProjectServiceAsync projectService = GWT.create(ProjectService.class);
	private ToDoServiceAsync toDoService = GWT.create(ToDoService.class);
	private EvaluationServiceAsync evaluationService = GWT.create(EvaluationService.class);
	private LogServiceAsync logService = GWT.create(LogService.class);

	public StudentToDoPage() {
		super();

		mainPanel = new VerticalPanel();
		initWidget(mainPanel);
		mainPanel.setSize("100%", "100%");

		HorizontalPanel horizontalPanel = new HorizontalPanel();
		mainPanel.add(horizontalPanel);
		mainPanel.setCellVerticalAlignment(horizontalPanel, HasVerticalAlignment.ALIGN_MIDDLE);
		mainPanel.setCellHorizontalAlignment(horizontalPanel, HasHorizontalAlignment.ALIGN_CENTER);
		horizontalPanel.setSize("100%", "30px");
		horizontalPanel.setSpacing(5);

		Label lblNewLabel = new Label("Team member:");
		lblNewLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		horizontalPanel.add(lblNewLabel);
		lblNewLabel.setWidth("96px");
		horizontalPanel.setCellVerticalAlignment(lblNewLabel, HasVerticalAlignment.ALIGN_MIDDLE);

		selectTeamMemberListBox = new ListBox();
		horizontalPanel.add(selectTeamMemberListBox);
		horizontalPanel.setCellWidth(selectTeamMemberListBox, "100%");
		selectTeamMemberListBox.setWidth("100%");
		horizontalPanel.setCellVerticalAlignment(selectTeamMemberListBox, HasVerticalAlignment.ALIGN_MIDDLE);
		selectTeamMemberListBox.addItem("Select a team member to view his/her to-dos...");

		selectTeamMemberListBox.addChangeHandler(new ChangeHandler() {

			@Override
			public void onChange(ChangeEvent event) {
				int selectedIndex = selectTeamMemberListBox.getSelectedIndex();
				if (selectedIndex != 0) {
					toDoTree.setVisible(true);
					selectedTeamMemberUserId = Long.valueOf(selectTeamMemberListBox.getValue(selectedIndex));
					loadToDos(selectedTeamMemberUserId);
				}
				else {
					toDoTree.setVisible(false);
				}
			}
		});

		toDoTree = new Tree();
		toDoTree.setAnimationEnabled(true);
		mainPanel.add(toDoTree);
		toDoTree.setSize("100%", "100%");
		toDoTree.setVisible(false);

		toDoTree.addOpenHandler(new OpenHandler<TreeItem>() {

			@Override
			public void onOpen(OpenEvent<TreeItem> event) {
				TreeItem item = (TreeItem)event.getTarget();
				if (item.getText().equals("Evaluation")) {
					loadEvaluation(item);
				}
				else if (item.getText().equals("Logs")) {
					loadLogs(item);
				}
			}
		});

	}

	public long getTeamId() {
		return teamId;
	}

	public void setTeamId(long teamId) {
		this.teamId = teamId;
	}

	public long getProjectId() {
		return projectId;
	}

	public void setProjectId(long projectId) {
		this.projectId = projectId;
	}

	public long getUserId() {
		return userId;
	}

	public void setUserId(long userId) {
		this.userId = userId;
	}

	public void loadTeamMembers() {
		selectTeamMemberListBox.clear();
		selectTeamMemberListBox.addItem("Select a team member to view his/her to-dos...");

		teamService.retrieveMembers(teamId, new AsyncCallback<List<UserDTO>>() {

			@Override
			public void onSuccess(List<UserDTO> result) {
				teamMembers = result;
				for (UserDTO userDTO : result) {
					selectTeamMemberListBox.addItem(userDTO.getFirstName() + " " + userDTO.getLastName() + " (" + userDTO.getUserName() + ")", String.valueOf(userDTO.getUserId()));
				}

			}

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Remote Procedure Call - Failure");				
			}
		});

	}

	public void loadProjectTutors() {

		projectService.retrieveTutors(projectId, new AsyncCallback<List<UserDTO>>() {

			@Override
			public void onSuccess(List<UserDTO> result) {
				projectTutors = result;
			}

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Remote Procedure Call - Failure");				
			}
		});

	}

	private void loadToDos(long studentId) {

		resetToDoTree();

		toDoService.retrieveToDosForStudent(studentId, teamId, new AsyncCallback<List<ToDoDTO>>() {

			@Override
			public void onSuccess(List<ToDoDTO> result) {

				for (ToDoDTO toDoDTO : result) {

					HorizontalPanel horizontalPanel_3 = new HorizontalPanel();
					horizontalPanel_3.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
					TreeItem toDoTreeItem = toDoTree.addItem(horizontalPanel_3);
					horizontalPanel_3.setSize("100%", "20px");
					toDoTreeItem.setWidth("100%");

					toDoTreeItem.setUserObject(toDoDTO);

					Label lblWeek = new Label(String.valueOf(toDoDTO.getWeek()));
					horizontalPanel_3.add(lblWeek);
					horizontalPanel_3.setCellHorizontalAlignment(lblWeek, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_3.setCellWidth(lblWeek, "20%");

					UserDTO student = null;

					for (UserDTO s : teamMembers) {
						if (s.getUserId() == toDoDTO.getStudentId())
							student = s;
					}

					Label lblStudent = new Label(student.getFirstName() + " " + student.getLastName() + " (" + student.getUserName() + ")");
					horizontalPanel_3.add(lblStudent);
					horizontalPanel_3.setCellHorizontalAlignment(lblStudent, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_3.setCellWidth(lblStudent, "20%");

					UserDTO tutor = null;

					for (UserDTO t : projectTutors) {
						if (t.getUserId() == toDoDTO.getTutorId())
							tutor = t;
					}

					Label lblTutor = new Label(tutor.getFirstName() + " " + tutor.getLastName() + " (" + tutor.getUserName() + ")");
					horizontalPanel_3.add(lblTutor);
					horizontalPanel_3.setCellHorizontalAlignment(lblTutor, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_3.setCellWidth(lblTutor, "20%");

					Label lblDate = new Label(toDoDTO.getDate().toString());
					horizontalPanel_3.add(lblDate);
					horizontalPanel_3.setCellHorizontalAlignment(lblDate, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_3.setCellWidth(lblDate, "20%");

					Label lblTitle = new Label(toDoDTO.getTitle());
					horizontalPanel_3.add(lblTitle);
					horizontalPanel_3.setCellHorizontalAlignment(lblTitle, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_3.setCellWidth(lblTitle, "20%");					

					VerticalPanel verticalPanel_1 = new VerticalPanel();
					TreeItem descriptionTreeItem = new TreeItem(verticalPanel_1);
					addTreeItemAndSetStyle(toDoTreeItem, descriptionTreeItem);
					verticalPanel_1.setWidth("100%");

					/*Label lblDescriptionText = new Label("Description:");
					verticalPanel_1.add(lblDescriptionText);
					lblDescriptionText.setSize("89px", "30px");*/

					Label lblDescription = new Label(toDoDTO.getDescription());
					lblDescription.getElement().getStyle().setProperty("whiteSpace", "pre");
					lblDescription.setWordWrap(true);
					verticalPanel_1.add(lblDescription);
					verticalPanel_1.setCellWidth(lblDescription, "100%");

					TreeItem evaluationTreeItem = new TreeItem("Evaluation");
					evaluationTreeItem.setUserObject(toDoDTO);
					addTreeItemAndSetStyle(toDoTreeItem, evaluationTreeItem);

					VerticalPanel verticalPanel_3 = new VerticalPanel();
					TreeItem evaluationTextTreeItem = new TreeItem(verticalPanel_3);
					addTreeItemAndSetStyle(evaluationTreeItem, evaluationTextTreeItem);
					verticalPanel_3.setWidth("100%");
					verticalPanel_3.setSpacing(5);


					TreeItem logsTreeItem = new TreeItem("Logs");
					logsTreeItem.setUserObject(toDoDTO);
					addTreeItemAndSetStyle(toDoTreeItem, logsTreeItem);

					HorizontalPanel horizontalPanel_4 = new HorizontalPanel();
					horizontalPanel_4.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
					TreeItem logsHeaderTreeItem = new TreeItem(horizontalPanel_4);
					addTreeItemAndSetStyle(logsTreeItem, logsHeaderTreeItem);
					horizontalPanel_4.setSize("100%", "30px");
					horizontalPanel_4.setBorderWidth(1);

					Label lblLogDate = new Label("Log date");
					horizontalPanel_4.add(lblLogDate);
					horizontalPanel_4.setCellHorizontalAlignment(lblLogDate, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_4.setCellWidth(lblLogDate, "33%");
					lblLogDate.setWidth("56px");

					Label lblWorkHour = new Label("Work hours");
					horizontalPanel_4.add(lblWorkHour);
					horizontalPanel_4.setCellHorizontalAlignment(lblWorkHour, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_4.setCellWidth(lblWorkHour, "33%");
					lblWorkHour.setWidth("70px");

					Label lblFile = new Label("File");
					horizontalPanel_4.add(lblFile);
					horizontalPanel_4.setCellHorizontalAlignment(lblFile, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_4.setCellWidth(lblFile, "33%");
					lblFile.setWidth("28px");			

				}

			}

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Remote Procedure Call - Failure");				
			}
		});

	}

	private void resetToDoTree() {
		toDoTree.removeItems();

		HorizontalPanel horizontalPanel_3 = new HorizontalPanel();
		horizontalPanel_3.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		toDoTree.addItem(horizontalPanel_3);
		horizontalPanel_3.setSize("100%", "30px");
		horizontalPanel_3.setBorderWidth(1);

		Label lblWeek = new Label("Week");
		horizontalPanel_3.add(lblWeek);
		horizontalPanel_3.setCellWidth(lblWeek, "20%");
		horizontalPanel_3.setCellHorizontalAlignment(lblWeek, HasHorizontalAlignment.ALIGN_CENTER);
		lblWeek.setWidth("35px");

		Label lblStudent = new Label("Student");
		horizontalPanel_3.add(lblStudent);
		horizontalPanel_3.setCellHorizontalAlignment(lblStudent, HasHorizontalAlignment.ALIGN_CENTER);
		horizontalPanel_3.setCellWidth(lblStudent, "20%");
		lblStudent.setWidth("48px");

		Label lblTutor = new Label("Tutor");
		horizontalPanel_3.add(lblTutor);
		horizontalPanel_3.setCellHorizontalAlignment(lblTutor, HasHorizontalAlignment.ALIGN_CENTER);
		horizontalPanel_3.setCellWidth(lblTutor, "20%");
		lblTutor.setWidth("35px");

		Label lblDate = new Label("Date");
		horizontalPanel_3.add(lblDate);
		horizontalPanel_3.setCellHorizontalAlignment(lblDate, HasHorizontalAlignment.ALIGN_CENTER);
		horizontalPanel_3.setCellWidth(lblDate, "20%");
		lblDate.setWidth("31px");

		Label lblTitle = new Label("Title");
		horizontalPanel_3.add(lblTitle);
		horizontalPanel_3.setCellHorizontalAlignment(lblTitle, HasHorizontalAlignment.ALIGN_CENTER);
		horizontalPanel_3.setCellWidth(lblTitle, "20%");
		lblTitle.setWidth("29px");
	}

	private void loadEvaluation(TreeItem evaluationTreeitem) {
		ToDoDTO toDoDTO = (ToDoDTO)evaluationTreeitem.getUserObject();

		evaluationTreeitem.removeItems();
		VerticalPanel verticalPanel_3 = new VerticalPanel();
		TreeItem evaluationTextTreeItem = new TreeItem(verticalPanel_3);
		addTreeItemAndSetStyle(evaluationTreeitem, evaluationTextTreeItem);
		verticalPanel_3.setWidth("100%");
		verticalPanel_3.setSpacing(5);

		evaluationService.retrieveEvaluation(toDoDTO.getTodoId(), new AsyncCallback<EvaluationDTO>() {

			@Override
			public void onSuccess(EvaluationDTO result) {

				TreeItem toDoTreeItem = getToDoTreeItem(result.getToDoId());

				if (toDoTreeItem == null) {
					return;
				}

				VerticalPanel verticalPanel = (VerticalPanel)toDoTreeItem.getChild(1).getChild(0).getWidget();

				if (result.getEvaluationId() == 0) {
					HorizontalPanel horizontalPanel_2 = new HorizontalPanel();
					verticalPanel.add(horizontalPanel_2);

					Label lblNoEvaluation = new Label("No evaluation yet from tutor!");
					lblNoEvaluation.getElement().getStyle().setProperty("whiteSpace", "pre");
					horizontalPanel_2.add(lblNoEvaluation);
					horizontalPanel_2.setCellWidth(lblNoEvaluation, "100%");
				}

				else {
					HorizontalPanel horizontalPanel_1 = new HorizontalPanel();
					verticalPanel.add(horizontalPanel_1);

					/*Label lblNewLabel_1 = new Label("Date:");
					horizontalPanel_1.add(lblNewLabel_1);
					lblNewLabel_1.setWidth("81px");*/

					Label lblDate = new Label(result.getDate().toString());
					horizontalPanel_1.add(lblDate);
					horizontalPanel_1.setCellWidth(lblDate, "100%");

					HorizontalPanel horizontalPanel_2 = new HorizontalPanel();
					verticalPanel.add(horizontalPanel_2);

					/*Label label = new Label("Description:");
					horizontalPanel_2.add(label);
					label.setWidth("81px");*/

					Label lblDescription = new Label(result.getDescription());
					lblDescription.getElement().getStyle().setProperty("whiteSpace", "pre");
					lblDescription.setWordWrap(true);
					horizontalPanel_2.add(lblDescription);
					horizontalPanel_2.setCellWidth(lblDescription, "100%");
				}
			}

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Remote Procedure Call - Failure");											
			}
		});


	}

	private void loadLogs(TreeItem logsTreeItem) {


		while (logsTreeItem.getChildCount() > 1) {
			logsTreeItem.removeItem(logsTreeItem.getChild(1));
		}

		HorizontalPanel horizontalPanel_5 = new HorizontalPanel();
		horizontalPanel_5.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		TreeItem uploadLogTreeItem = new TreeItem(horizontalPanel_5);
		uploadLogTreeItem.setUserObject(logsTreeItem.getUserObject());
		addTreeItemAndSetStyle(logsTreeItem, uploadLogTreeItem);
		horizontalPanel_5.setSize("100%", "30px");

		TreeItemButton btnUploadNewLog = new TreeItemButton("Upload new log");
		btnUploadNewLog.setParentTreeItem(uploadLogTreeItem);
		horizontalPanel_5.add(btnUploadNewLog);
		if (userId != selectedTeamMemberUserId)
			btnUploadNewLog.setEnabled(false);

		btnUploadNewLog.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				TreeItemButton button = (TreeItemButton) event.getSource();

				TreeItem uploadLogTreeItem =  button.getParentTreeItem();
				uploadLogTreeItem.removeItems();

				FlexTable flexTable = new FlexTable();
				flexTable.setWidth("100%");

				Label lblNewLog = new Label("New Log");
				flexTable.setWidget(0, 0, lblNewLog);
				lblNewLog.setWidth("70px");

				Label lblWorkHours = new Label("Work hours");
				flexTable.setWidget(1, 0, lblWorkHours);
				lblWorkHours.setWidth("70px");

				DoubleBox workHoursDoubleBox = new DoubleBox();
				flexTable.setWidget(1, 1, workHoursDoubleBox);
				workHoursDoubleBox.setWidth("100%");

				Label lblDescription = new Label("Description");
				flexTable.setWidget(2, 0, lblDescription);
				lblDescription.setWidth("77px");

				TextArea descriptionTextArea = new TextArea();
				flexTable.setWidget(2, 1, descriptionTextArea);
				descriptionTextArea.setWidth("100%");

				TreeItemButton cancelButton = new TreeItemButton("Cancel");
				cancelButton.setParentTreeItem(uploadLogTreeItem);
				flexTable.setWidget(3, 0, cancelButton);

				cancelButton.addClickHandler(new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						TreeItemButton button = (TreeItemButton) event.getSource();

						TreeItem logsTreeItem =  button.getParentTreeItem().getParentItem();
						if(logsTreeItem != null) {
							loadLogs(logsTreeItem);
						}

					}
				});

				TreeItemButton saveButton = new TreeItemButton("Save");
				saveButton.setParentTreeItem(uploadLogTreeItem);
				flexTable.setWidget(3, 1, saveButton);

				saveButton.addClickHandler(new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						TreeItemButton button = (TreeItemButton) event.getSource();

						TreeItem uploadLogTreeItem =  button.getParentTreeItem();
						ToDoDTO toDoDTO = (ToDoDTO)uploadLogTreeItem.getUserObject();

						FlexTable flexTable = (FlexTable) uploadLogTreeItem.getWidget();
						DoubleBox workHoursDoubleBox = (DoubleBox) flexTable.getWidget(1, 1);
						TextArea descriptionTextArea = (TextArea) flexTable.getWidget(2, 1);

						LogDTO logDTO = new LogDTO();
						logDTO.setToDoId(toDoDTO.getTodoId());								
						logDTO.setDate(new Date());
						logDTO.setWorkHour(workHoursDoubleBox.getValue() != null ? workHoursDoubleBox.getValue() : 0.0);
						logDTO.setDescription(descriptionTextArea.getText());

						logService.createLog(logDTO, new AsyncCallback<Long>() {

							@Override
							public void onSuccess(Long result) {
								TreeItem toDoTreeItem = getToDoTreeItem(result);
								if(toDoTreeItem != null) {
									loadLogs(toDoTreeItem.getChild(2));
								}
							}

							@Override
							public void onFailure(Throwable caught) {
								Window.alert("Remote Procedure Call - Failure");

							}
						});

					}
				});

				uploadLogTreeItem.setWidget(flexTable);						

			}
		});

		ToDoDTO toDoDTO = (ToDoDTO)logsTreeItem.getUserObject();

		logService.retrieveLogs(toDoDTO.getTodoId(), new AsyncCallback<List<LogDTO>>() {

			@Override
			public void onSuccess(List<LogDTO> result) {
				if (result == null || result.size() == 0) {
					return;
				}

				TreeItem toDoTreeItem = getToDoTreeItem(result.get(0).getToDoId());

				TreeItem logsTreeItem = toDoTreeItem.getChild(2);

				for (LogDTO logDTO : result) {

					HorizontalPanel horizontalPanel_4 = new HorizontalPanel();
					horizontalPanel_4.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
					TreeItem logTreeItem = new TreeItem(horizontalPanel_4);
					logTreeItem.setUserObject(logDTO);
					addTreeItemAndSetStyle(logsTreeItem, logTreeItem);
					horizontalPanel_4.setSize("100%", "30px");

					Label lblLogDate = new Label(logDTO.getDate().toString());
					horizontalPanel_4.add(lblLogDate);
					horizontalPanel_4.setCellHorizontalAlignment(lblLogDate, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_4.setCellWidth(lblLogDate, "33%");

					Label lblWorkHour = new Label(String.valueOf(logDTO.getWorkHour()));
					horizontalPanel_4.add(lblWorkHour);
					horizontalPanel_4.setCellHorizontalAlignment(lblWorkHour, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_4.setCellWidth(lblWorkHour, "33%");

					TreeItemButton fileDownloadButton = new TreeItemButton("Download attached file");
					fileDownloadButton.setParentTreeItem(logTreeItem);
					horizontalPanel_4.add(fileDownloadButton);
					horizontalPanel_4.setCellHorizontalAlignment(fileDownloadButton, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_4.setCellWidth(fileDownloadButton, "33%");

					if (logDTO.getAttachedFileName() == null || logDTO.getAttachedFileName().isEmpty())
						fileDownloadButton.setEnabled(false);
					fileDownloadButton.addClickHandler(downloadButtonClickHandler);


					VerticalPanel verticalPanel = new VerticalPanel();
					TreeItem logDetailsTreeItem = new TreeItem(verticalPanel);
					logDetailsTreeItem.setUserObject(logDTO);
					addTreeItemAndSetStyle(logTreeItem, logDetailsTreeItem);
					verticalPanel.setWidth("100%");
					verticalPanel.setSpacing(10);

					HorizontalPanel horizontalPanel_1 = new HorizontalPanel();
					verticalPanel.add(horizontalPanel_1);

					Label lblDescription = new Label(logDTO.getDescription());
					lblDescription.getElement().getStyle().setProperty("whiteSpace", "pre");
					lblDescription.setWordWrap(true);
					horizontalPanel_1.add(lblDescription);
					horizontalPanel_1.setCellWidth(lblDescription, "100%");

					HorizontalPanel horizontalPanel_2 = new HorizontalPanel();
					verticalPanel.add(horizontalPanel_2);
					horizontalPanel_2.setWidth("100%");

					TreeItemButton btnModifyLog = new TreeItemButton("Modify log");
					horizontalPanel_2.add(btnModifyLog);
					btnModifyLog.setParentTreeItem(logDetailsTreeItem);
					if (userId != selectedTeamMemberUserId)
						btnModifyLog.setEnabled(false);

					MultiUploader logFileUploader = new MultiUploader();
					logFileUploader.setServletPath("/consulttime/logfileupload");
					logFileUploader.setFileInputPrefix(String.valueOf(logDTO.getLogId()));
					logFileUploader.setMaximumFiles(1);
					logFileUploader.addOnFinishUploadHandler(onFinishLogFileUploaderHandler);

					horizontalPanel_2.add(logFileUploader);

					TreeItemButton btnDeleteLog = new TreeItemButton("Delete log");
					horizontalPanel_2.add(btnDeleteLog);
					btnDeleteLog.setParentTreeItem(logDetailsTreeItem);
					if (userId != selectedTeamMemberUserId)
						btnDeleteLog.setEnabled(false);

					btnModifyLog.addClickHandler(new ClickHandler() {

						@Override
						public void onClick(ClickEvent event) {
							TreeItemButton button = (TreeItemButton) event.getSource();

							TreeItem logTreeItem =  button.getParentTreeItem().getParentItem();
							logTreeItem.removeItems();

							LogDTO logDTO = (LogDTO) logTreeItem.getUserObject();

							FlexTable flexTable = new FlexTable();
							flexTable.setWidth("100%");

							Label lblModifyLog = new Label("Modify Log");
							flexTable.setWidget(0, 0, lblModifyLog);
							lblModifyLog.setWidth("70px");

							Label lblWorkHours = new Label("Work hours");
							flexTable.setWidget(1, 0, lblWorkHours);
							lblWorkHours.setWidth("70px");

							DoubleBox workHoursDoubleBox = new DoubleBox();
							workHoursDoubleBox.setValue(logDTO.getWorkHour());
							flexTable.setWidget(1, 1, workHoursDoubleBox);
							workHoursDoubleBox.setWidth("100%");

							Label lblDescription = new Label("Description");
							flexTable.setWidget(2, 0, lblDescription);
							lblDescription.setWidth("77px");

							TextArea descriptionTextArea = new TextArea();
							descriptionTextArea.setText(logDTO.getDescription());
							flexTable.setWidget(2, 1, descriptionTextArea);
							descriptionTextArea.setWidth("100%");

							TreeItemButton cancelButton = new TreeItemButton("Cancel");
							cancelButton.setParentTreeItem(logTreeItem);
							flexTable.setWidget(3, 0, cancelButton);

							cancelButton.addClickHandler(new ClickHandler() {

								@Override
								public void onClick(ClickEvent event) {
									TreeItemButton button = (TreeItemButton) event.getSource();

									TreeItem logsTreeItem =  button.getParentTreeItem().getParentItem();
									if(logsTreeItem != null) {
										loadLogs(logsTreeItem);
									}

								}
							});

							TreeItemButton saveButton = new TreeItemButton("Save");
							saveButton.setParentTreeItem(logTreeItem);
							flexTable.setWidget(3, 1, saveButton);

							saveButton.addClickHandler(new ClickHandler() {

								@Override
								public void onClick(ClickEvent event) {
									TreeItemButton button = (TreeItemButton) event.getSource();

									TreeItem logTreeItem =  button.getParentTreeItem();
									LogDTO logDTO = (LogDTO) logTreeItem.getUserObject();

									FlexTable flexTable = (FlexTable) logTreeItem.getWidget();
									DoubleBox workHoursDoubleBox = (DoubleBox) flexTable.getWidget(1, 1);
									TextArea descriptionTextArea = (TextArea) flexTable.getWidget(2, 1);

									logDTO.setDate(new Date());
									logDTO.setWorkHour(workHoursDoubleBox.getValue() != null ? workHoursDoubleBox.getValue() : 0.0);
									logDTO.setDescription(descriptionTextArea.getText());

									logService.updateLog(logDTO, new AsyncCallback<Long>() {

										@Override
										public void onSuccess(Long result) {
											TreeItem toDoTreeItem = getToDoTreeItem(result);
											if(toDoTreeItem != null) {
												loadLogs(toDoTreeItem.getChild(2));
											}
										}

										@Override
										public void onFailure(Throwable caught) {
											Window.alert("Remote Procedure Call - Failure");

										}
									});

								}
							});

							logTreeItem.setWidget(flexTable);														

						}
					});

					btnDeleteLog.addClickHandler(new ClickHandler() {

						@Override
						public void onClick(ClickEvent event) {
							TreeItemButton button = (TreeItemButton) event.getSource();

							LogDTO logDTO = (LogDTO) button.getParentTreeItem().getUserObject();

							logService.deleteLog(logDTO.getLogId(), new AsyncCallback<Long>() {

								@Override
								public void onSuccess(Long result) {
									TreeItem toDoTreeItem = getToDoTreeItem(result);
									if(toDoTreeItem != null) {
										loadLogs(toDoTreeItem.getChild(2));
									}
								}

								@Override
								public void onFailure(Throwable caught) {
									Window.alert("Remote Procedure Call - Failure");
								}


							});
						}
					});

				}

			}

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Remote Procedure Call - Failure");											
			}
		});
	}

	private IUploader.OnFinishUploaderHandler onFinishLogFileUploaderHandler = new IUploader.OnFinishUploaderHandler() {
		public void onFinish(IUploader uploader) {
			if (uploader.getStatus() == Status.SUCCESS) {

				// The server sends useful information to the client by default
				UploadedInfo info = uploader.getServerInfo();
				//System.out.println("File name " + info.name);
				//System.out.println("File content-type " + info.ctype);
				//System.out.println("File size " + info.size);

				// You can send any customized message and parse it 
				//System.out.println("Server message " + info.message);
				
				if (info != null) {
					long updatedLogsToDoID = Long.valueOf(info.message);

					loadLogs(getToDoTreeItem(updatedLogsToDoID).getChild(2));
				}
			}
		}
	};
	
	private ClickHandler downloadButtonClickHandler = new ClickHandler() {
		
		@Override
		public void onClick(ClickEvent event) {
			TreeItemButton button = (TreeItemButton) event.getSource();

			TreeItem logTreeItem =  button.getParentTreeItem();
			LogDTO logDTO = (LogDTO) logTreeItem.getUserObject();
			
			Window.open("/consulttime/logfiledownload?logid="+logDTO.getLogId(), "_blank", null);
			
		}
	};
	
	private void addTreeItemAndSetStyle(TreeItem parent, TreeItem child) {
		parent.addItem(child);

		Element div = parent.getElement();
		Element table = DOM.getFirstChild(div);
		Element tbody = DOM.getFirstChild(table);
		Element tr = DOM.getFirstChild(tbody);
		Element td = DOM.getChild(tr, 1);
		td.getStyle().setWidth(100, Unit.PCT);
	}

	private TreeItem getToDoTreeItem(long toDoId) {
		for (int i = 1, count = toDoTree.getItemCount(); i < count; i++) {
			TreeItem treeItem = toDoTree.getItem(i);
			ToDoDTO toDoDTO = (ToDoDTO)treeItem.getUserObject();
			if (toDoId == toDoDTO.getTodoId()) {
				return treeItem;
			}
		}
		return null;
	}

}
